﻿/// <reference path="../core/jquery-1.4.2.min-vsdoc.js"/>
/// <reference path="../config/sw-config-default.js"/>
/// <reference path="../core/sw-prototype.js"/>
/// <reference path="../core/sw.js"/>
/// <reference path="../core/sw-control-core.js"/>

/***************************************************************************
jQuery GridView
NOTE: Created for SmartUI. 
Copyright 2010, Roy zhang
Features：
1.数据格式化、排序;表头大小设置;固定表头
2.单选、多选列；其定义列
3.翻页（两种格式）
4.
Update Note：

Needs：jquery.tmpl.js
****************************************************************************/

(function ($) {
    ///#region 设置
    var gridsetting = {
        id: '_gird'
            , tbheadid: '_tbhead'
            , tbdataid: '_tb'
            , tbhcss: 'gridheader' 
             , thcss: 'gridth'
            , tbcss: 'grid'
            , trcss: 'gridrow'
            , altertrcss: 'gridalterrow'
            , tfcss: ''                   
    };

    ///#endregion

    $.fn.gridview = function (options, datasource, totalrecord, fnpagechanged) {
        /// <summary>Grid View</summary>
        /// <param name="options" type="Array">配置项</param>
        /// <param name="datasource" type="Json">数据源</param>
        var grid = this, id = grid.attr('id');
        ///#region 属性 

        options = $.extend({
            css: "gridview"
            , width: iconfig.grid.width                      //宽度
            , height: iconfig.grid.height                   //高度
            , sortable: true                //是否排序
            , usepager: true                //是否分页
            , showtoppager: false
            , columnresize: true            //表头是否可以设置大小
            , showseq: true                 //是否显示序号
            , showchk: false                //是否显示checkbox
            , chkfield: ''                  //checkbox绑定字段
            , showradio: false              //是否显示radio
            , radiofield: ''                //radio绑定字段
            , columns: []                   //列设置
            , sort: null                    //排序
            , ajax: null                    //ajax设置如：ajax:{url: null, data: null}
            , pagesize: iconfig.grid.pagesize
            , pageindex: 1
            , totalrecord: 0
            , fnBuilded: null               //自定义数据绑定事件fnBuilded(items, datas);
            , fnSorted: null                //自定义排序事件fnSorted(ops,grid);
        }, options);
        options.text = $.extend({
            seqtext: $iconst.controls.grid.seqtext
                , radiotext: $iconst.controls.grid.radiotext
        }, options.text);
        ///#endregion

        ///#region 私有变量
        var _tdwidth = 0, _iscolmove, _tx, _clindex, _issort = true;
        ///#endregion

        ///#region 主体内容
        grid = this.addClass(options.css);

        ///#region build Header and TR Template
        var header = $(document.createElement('div')).addClass('head');
        var headpanel = $('<div onselectstart="return false;" />').addClass('gridheadpanel').appendTo(header); //表头区域
        var tbhead = $(document.createElement('table')).attr("id", id + gridsetting.tbheadid).addClass(gridsetting.tbhcss).width(10).appendTo(headpanel);

        var datapanel = $(document.createElement('div')).addClass('griddatapanel').width(options.width).height(options.height); //数据区域
        var tb = $(document.createElement('table')).width(10).addClass(gridsetting.tbcss).attr("id", id + gridsetting.tbdataid);

        buildColumn(tbhead, datapanel); //生成列
        tb.appendTo(datapanel);
        grid.append(header).append(datapanel);
        //设置grid宽度
        if (parseInt(grid.css('width')) > options.width + 20)
            grid.width(options.width);
        ///#endregion

        if (!fnpagechanged && options.ajax && options.ajax.url)
            fnpagechanged = function (pageindex, pagesize) { pageChanged(null, id, pageindex, pagesize); };

        buildPager(grid, options, fnpagechanged);

        bindGrid(false, id, grid, datasource, totalrecord, { sort: options.sort ? options.sort : '',
            ajax: options.ajax, pagesize: options.pagesize, pageindex: options.pageindex, fnBuilded: options.fnBuilded
        }, fnpagechanged);


        return grid;
        ///#endregion

        ///#region 私有方法
        function buildColumn(tbh, datapanel) {
            /// <summary>生成Grid</summary>
            /// <param name="datas" type="Json">Json数据源</param>
            /// <param name="total" type="Number">总记录条数</param>            
            /// <param name="pagechange" type="Function">翻页事件</param>
            /// <param name="grid" type="JQDom">Grid</param>
            var th = new StringBuilder();
            var tr = new StringBuilder();
            th.append('<thead><tr class="').append(gridsetting.thcss).append('">');
            tr.append('<tr class="{{if $itemindex %2 == 0 }}').append(gridsetting.altertrcss).append('{{else}}').append(gridsetting.trcss).append('{{/if}}">');
            var column;
            ///#region 设置初始化项
            if (options.showseq) {//序号
                th.append('<th style="width:30px" class="seq">').append(options.text.seqtext).append('</th>');
                tr.append('<td class="seq">${$itemindex}</td>');
            }
            if (options.showchk) {//多选
                th.append('<th style="width:30px"><input type="checkbox" id="').append(id).append('_chkAll"/></th>');
                tr.append('<td class="center"><input type="checkbox" class="').append(id).append('" value="${').append(options.chkfield).append('}"/></td>');
            }
            if (options.showradio) {//单选
                th.append('<th style="width:40px">').append(options.text.radiotext).append('</th>');
                tr.append('<td class="center"><input type="radio" name="').append(id).append('" value="${').append(options.radiofield).append('}"/></td>');
            }
            ///#endregion

            for (var i = 0; options.columns[i]; i++) {
                column = options.columns[i];
                ///#region Th
                th.append('<th style="width:').append(column.width).append('" col="').append(i + '').append('"');
                if (options.sortable && column.sort)
                    th.append(' class="thsort" cf="').append(column.sortfield || column.field).append('"><div class="sort">&nbsp;</div>');
                else
                    th.append('>');
                if (options.columnresize)
                    th.append('<div class="resizer">&nbsp;</div>')

                th.append('<span class="thtext">').append(column.name).append('</span></th>')
                ///#endregion
                ///#region tr
                tr.append('<td').append(' col="').append(i + '').append('"');
                tr = buildTr(column, tr);
                tr.append('</td>');
                ///#endregion
            }
            th.append('</tr></thead>');
            tr.append('</tr>');
            $.templates(id, tr.toString());
            tbh.append(th.toString());
            setThEvent(tbh, datapanel);
        }
        function buildTr(column, tr) {
            var field, css;
            if (column.custom) {//自定义html
                css = column.type;
                field = column.custom;
            } else {
                if (column.type && column.type.length > 0) {//定义类型时
                    switch (column.type) {//数据格式化
                        case "int":
                            css = 'right';
                            break;
                        case "num":
                            css = 'right';
                            field = 'toDecimal(' + column.field + (column.format ? ',' + column.format * 1 : '') + ')';
                            break;
                        case "date":
                            css = 'center';
                            field = 'toDateStr(' + column.field + ',false' + (column.format ? ',' + column.format * 1 : '') + ')';
                            break;
                        case "datetime":
                            css = 'center';
                            field = 'toDateStr(' + column.field + ',true' + (column.format ? ',' + column.format * 1 : '') + ')';
                            break;
                        case "cur":
                            css = 'cur';
                            field = 'toDecimal(' + column.field + (column.format ? ',' + column.format * 1 : '') + ')';
                            break;
                        case "enum":
                            css = 'center';
                            field = 'toEnum(' + column.field + ',"' + column.format + '")';
                            break;
                        case "bool":
                            css = 'center';
                            field = 'toBoolView(' + column.field + ',true)';
                            break;
                        case "hid":
                            css = 'hid';
                            break;
                    }
                }
                field = field ? field : column.field;
                field = '${' + field + '}';
            }
            if (column.css)//设置的css优先
                css = column.css
            css = css ? ' class="' + css + '"' : '';
            tr.append(css).append('>').append(field);
            return tr;
        }
        function setThEvent(tbh, datapanel) {
            tbh.find('tr > th').each(function () {
                var th = $(this);
                ///#region 页头拖动设置
                if (options.columnresize) {
                    th.find('div.resizer').mousedown(function (e) {
                        var event = window.event || e;
                        _tx = event.x || event.clientX;
                        var td = $(this).parent();
                        _tdwidth = parseInt(td.css('width'));
                        _clindex = td.attr("col");
                        _iscolmove = true;
                        _issort = false;
                    });
                    $(document).mousemove(function (e) {
                        if (_iscolmove) {
                            var event = window.event || e;
                            var th = $('#' + id + gridsetting.tbheadid + ' th[col="' + _clindex + '"]');
                            var width = _tdwidth + (event.x || event.clientX) - _tx;
                            var textwidth = th.children('span.thtext').width() + 16;
                            th.css('width', textwidth > width ? textwidth : width);
                        }
                    });
                    $(document).mouseup(function () {
                        if (_iscolmove) {
                            _tx = 0;
                            _iscolmove = false;
                            $('#' + id + gridsetting.tbdataid + ' tr:first td[col="' + _clindex + '"]').css('width', $('#' + id + gridsetting.tbheadid + ' th[col="' + _clindex + '"]').css('width'));
                            $('#' + id + gridsetting.tbheadid).css('margin-left', -parseInt($('#' + id + ' .griddatapanel').attr('scrollLeft')));
                        }
                    });
                }
                ///#endregion

                ///#region 表头排序
                if (options.sortable) {
                    var sortname = th.attr('cf');
                    if (strNotEmpty(sortname) && th.hasClass('thsort')) {
                        if (options.sort) {
                            var startindex = options.sort.indexOf(sortname + ' ');
                            if (startindex > -1)
                                th.find('div.sort').addClass(options.sort.indexOf(sortname + ' desc') > -1 ? 'desc' : 'asc');
                        }
                        var fnsort = options.fnSorted;
                        th.click(function () {
                            if (_issort) {
                                var th = $(this), divsort = th.find('div.sort'), _sort = divsort.hasClass('asc') ? 'desc' : 'asc';
                                divsort.addClass('desc').removeClass('asc');
                                th.parent().find('th > div.sort').attr('class', 'sort');
                                divsort.addClass(_sort);
                                var grid = $('#' + id), ops = grid.data('ops');
                                ops.sort = th.attr('cf') + ' ' + _sort;
                                if (fnsort)
                                    fnsort(ops, grid);
                                else
                                    bindGrid(true, id, grid, null, null, ops);
                            }
                            else
                                _issort = true;
                        });
                    }
                }
                ///#endregion

                ///#region 多选
                if (options.showchk)
                    tbh.find(':checkbox').click(function () {
                        $('#' + id + " :checkbox." + id).attr("checked", this.checked);
                    });
                ///#endregion
            });

            datapanel.scroll(function () {
                $('#' + id + gridsetting.tbheadid).css('margin-left', -parseInt($('#' + id + ' .griddatapanel').attr('scrollLeft')));
            });
        }
        function buildPager(container, ops, fnpagechange) {
            /// <summary>生成Pager</summary>
            if (ops.usepager) {
                var pageops = { pagesize: ops.pagesize, pageindex: ops.pageindex, totalrecord: ops.totalrecord };
                $(document.createElement('div')).pager(pageops, fnpagechange).appendTo(container);
                if (ops.showtoppager)
                    $(document.createElement('div')).pager(pageops, fnpagechange).prependTo(container);
            }
        }
        ///#endregion
    };

    $.fn.girdviewReload = function (options, datasource) {
        /// <summary>重新绑定grid</summary>
        /// <param name="datasource" type="Json">Json数据源</param>
        var grid = this, id = grid.attr('id'),ops;
        if (options) {
            ops = $.extend(grid.data('ops'), options);
            if (options.ajax && options.ajax.url)
                ops.ajax = $.extend(ops.ajax, options.ajax);
        }
        else
            ops = grid.data('ops');
        if (!options || !options.pageindex)
            ops.pageindex = 1;
        pageChanged(grid, id, null, null, datasource,ops);
    }

    ///#region 内部方法
    function bindGrid(isreload, id, grid, datas, totalrecord, ops, fnpagechanged) {
        if (ops.ajax && ops.ajax.url) {
            ictrcore.loading(grid);
            ictrcore.GetDatas(ops.ajax.url, $sw.bulidSearchParam(ops.pageindex, ops.pagesize, ops.ajax.data, ops.sort),
                                 function (datas) {
                                     if (datas)
                                         buildGrid(isreload, id, grid, datas.rows, datas.total, ops, fnpagechanged);
                                     else
                                         buildGrid(isreload, id, grid, null, 0, ops, fnpagechanged);
                                 }, function () {
                                     buildGrid(isreload, id, grid, null, 0, ops, fnpagechanged);
                                 });
        }
        else
            buildGrid(isreload, id, grid, datas, totalrecord, ops, fnpagechanged);
    }
    function buildGrid(isreload, id, grid, datas, totalrecord, ops, fnpagechanged) {

        if (totalrecord)
            ops.totalrecord = totalrecord;
        var tb = grid.find('#' + id + gridsetting.tbdataid);
        if (isreload)
            tb.html(''); //移除原有数据

        grid.find('div.pager').pager({ pagesize: ops.pagesize, pageindex: ops.pageindex, totalrecord: ops.totalrecord });
        if (datas != null && datas.length > 0) {
            var items = $.tmpl(id, datas, { startIndex: (ops.pageindex - 1) * ops.pagesize }).appendTo(tb);
            if (ops.fnBuilded)
                ops.fnBuilded(items, datas);
        }
        setTr(grid.find('#' + id + gridsetting.tbheadid), tb);
        grid.data('ops', ops);
        ictrcore.loadingClose(grid);
    }

    function pageChanged(grid, id, pageindex, pagesize, datasource,ops) {
        /// <summary>翻页处理</summary>
        /// <param name="pageindex" type="Number">页码</param>
        /// <param name="datasource" type="Json">Json数据源</param>
        if (!grid)
            grid = $('#' + id);
        if(!ops)
            ops = grid.data('ops');

        if (pagesize)
            ops.pagesize = pagesize;
        if (pageindex)
            ops.pageindex = pageindex;
        bindGrid(true, id, grid, datasource, null, ops)
    }
    function setTr(tbh, tb) {
        /// <summary>设置数据Table的TR样式与表头对应</summary>
        /// <param name="tbh" type="JQDom">表头Table</param>
        /// <param name="tb" type="JQDom">数据Table</param>
        var tds = tb.find('tr:first td');
        var ths = tbh.find('th').each(function (i) {
            tds.eq(i).css('width', $(this).css('width'));
        });
    }
    ///#endregion
})(jQuery);